home *** CD-ROM | disk | FTP | other *** search
- /*
-
- _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
-
- NSTRING - a dynamic string class based on the string handling
- functions of the NEWTON programming language.
- NEWTON is being developed for VAX/VMS and DEC Alpha
- systems by the staff of the compilation lab (LCO) of the
- Swiss Federal Institute of Technology (EPFL).
-
- Version 1.0 - beta
-
- Copyright © 20th November, 1994 by Joël "Obiwan" François
-
- _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
-
- */
-
- #ifndef _NSTRING_H_
- #define _NSTRING_H_
-
- #include <iostream.h>
- #include "Alphabet.h"
-
- class NString
- {
- public:
-
- // NOTE: Unless otherwise specified, the reference returned by functions that return
- // an NString& is always a reference to the current NString object, to allow concatenation
- // of NString operations.
-
-
- /*-------- Public Constructors & Destructor --------*/
-
- NString (void); // NString s;
- // constructor: create an empty NString.
-
- NString (const char *s); // NString s("Hello World");
- // constructor: NString initialized with a given C-String.
-
- NString (const char c); // NString s('P');
- // constructor: NString initialized with a character.
- // If the character is a NUL character, a runtime error will be raised.
-
- inline NString (const NString& s); // NString s(a);
- // constructor: NString copied from an existing NString.
-
- ~NString (void);
- // destructor
-
- /*-------- Assignment --------*/
-
- NString& operator= (const char *s); // s = "Hello World";
- // build an NString from a C-String
-
- NString& operator= (const char c); // s = 'M';
- // build an NString from a character
- // If the character is a NUL character, a runtime error will be raised.
-
- NString& operator= (const NString& s); // s = t;
- // copy an NString
-
- /*-------- Getting at the information contained in an NString --------*/
-
- char *string (void) const; // C_str = s.stringcopy();
- // get a copy of the C-String contained in the NString.
- // NOTE: You must free() the returned pointer after usage.
-
- inline char *string (char *s) const; // s.string(C_str);
- // get a copy of the C-String contained in the NString.
- // The provided char pointer is used to store the copy.
- // WARNING: The provided buffer must be large enough
- // to hold the string; no boundary checks are done !
-
- // NOTE: The string() functions return solely a COPY of the C-string contained in the NString.
- // It is NOT possible to return a pointer to the original string, as this pointer might change
- // during subsequent NString-operations ! Moreover, this way the class user cannot
- // corrupt class integrity by modifying string data directly.
-
- inline unsigned long int length (void) const; // l = s.length();
- // get the length of the NString
-
- /*-------- Accessing single characters in the NString --------*/
-
- char operator[] (const unsigned long int k) const; // c = s[3];
- // read the kth character of the NString; s[1] is the first character;
- // if (k > s.length) a runtime error will occur.
- // Thus the terminating NUL-byte can't be read.
-
- char setchar (const unsigned long int k, const char c); // s.setchar(2, 'Q');
- // modify the kth character of the NString; the first character is numbered 1;
- // if (k > s.length) a runtime error will occur. Thus the terminating NUL-byte can't be modified.
- // This is necessary to prevent corruption of the NString by altering it's terminator.
- // Also, if (c == '\0') a runtime error will be raised, as placing a NUL character in the middle
- // of the NString would corrupt it.
- // The return value is the character that formerly resided at index k in the NString.
-
- /*-------- Comparing NStrings --------*/
-
- inline int operator== (const char *s) const; // if (s == "Yes") ...;
-
- inline int operator!= (const char *s) const; // if (s != "No") ...;
-
- inline int operator>= (const char *s) const; // if (s >= "alpha") ...;
-
- inline int operator<= (const char *s) const; // if (s <= "beta") ...;
-
- inline int operator> (const char *s) const; // if (s > "alpha") ...;
-
- inline int operator< (const char *s) const; // if (s < "beta") ...;
-
- inline int compare (const char *s) const; // if (s.compare("Hello") == 0) ...;
- // simply returns the result of strcmp()
- // zero means (*this == s)
- // greater than zero means (*this > s)
- // less than zero means (*this < s)
-
- inline int operator== (const NString& s) const; // if (s == t) ...;
-
- inline int operator!= (const NString& s) const; // if (s != t) ...;
-
- inline int operator>= (const NString& s) const; // if (s >= t) ...;
-
- inline int operator<= (const NString& s) const; // if (s <= t) ...;
-
- inline int operator> (const NString& s) const; // if (s > t) ...;
-
- inline int operator< (const NString& s) const; // if (s < t) ...;
-
- inline int compare (const NString& s) const; // if (s.compare(t) != 0) ...;
- // simply returns the result of strcmp()
- // zero means (*this == s)
- // greater than zero means (*this > s)
- // less than zero means (*this < s)
-
- inline int operator== (const char c) const; // if (s == 'R') ...;
-
- inline int operator!= (const char c) const; // if (s != 'L') ...;
-
- inline int operator>= (const char c) const; // if (s >= 'A') ...;
-
- inline int operator<= (const char c) const; // if (s <= 'B') ...;
-
- inline int operator> (const char c) const; // if (s > 'A') ...;
-
- inline int operator< (const char c) const; // if (s < 'B') ...;
-
- inline int compare (const char c) const; // if (s.compare('N') == 0) ...;
- // 0 means (*this == c)
- // 1 means (*this > s)
- // -1 means (*this < s)
-
-
- inline const NString& min (const NString& other) const; // t = s.min(NString("help"));
- // return this NString if (*this < other), "other" otherwise.
-
- inline const NString& max (const NString& other) const; // t = s.max(t);
- // return this NString if (*this > other), "other" otherwise
-
- /*-------- Concatenating NStrings --------*/
-
- // Note: An attempt to add a NUL character to an NString will always result in a runtime error.
-
- NString& operator+= (const char *s); // s += ".txt";
- // extend an NString by adding a C-String
-
- NString& operator+= (const NString& s); // s += t;
- // extend an NString by adding another NString
-
- NString& operator+= (const char c); // s += 'c';
- // extend an NString by adding a character
-
- NString operator+ (const char *s) const; // u = s + ".sit";
- // create a new NString that is the concatenation of
- // an NString with a C-String
-
- NString operator+ (NString& s) const; // u = s + t;
- // create a new NString that is the concatenation of
- // two NStrings
-
- NString operator+ (const char c) const; // u = s + 'M';
- // create a new NString that is the concatenation of
- // an NString with a character
-
- friend NString operator+ (const char *s, const NString& ns); // s = "***" + t;
- // form a new NString by inserting a C-String at the
- // beginning of an NString.
-
- friend NString operator+ (const char c, const NString& ns); // s = '>' + t;
- // form a new NString by adding a character to the
- // beginning of an NString.
-
- NString& operator*= (const unsigned long int k); // s *= 2;
- // change the NString to k times its original string
- // k==0 results in an empty string; k==1 leaves the NString unchanged
-
- NString operator* (const unsigned long int k) const; // s = t * 3;
- // build a new NString consisting of the original string k times concatenated
- // k==0 results in an empty string; k==1 returns a copy of the original NString
-
- /*-------- Copying parts of an NString --------*/
-
- NString fromto (unsigned long int from, unsigned long int to) const; // t = s.fromto(2,5)
- // return an NString consisting of the substring of the original NString
- // ranging from character # "from" to character # "to".
- // The first character is counted as # 1, the last as # s.length().
- // Both of the border characters are included in the new string.
- // If either parameter is out of range, only the valid part is returned.
- // If "from" > "to", an empty NString is returned.
-
- inline NString from (unsigned long int from) const; // t = s.from(3);
- // return the substring ranging from character # "from" to
- // the end of the original NString.
- // This function is equivalent to "s.fromto(from, s.length())"
- // The considerations stated under "fromto" apply.
-
- inline NString to (unsigned long int to) const; // t = s.to(5);
- // return the substring ranging from the beginning of the
- // original NString to character # "to".
- // This function is equivalent to "s.fromto(0, to)"
- // The considerations stated under "fromto" apply.
-
- /*-------- Cutting parts out of an NString --------*/
-
- NString& cut(unsigned long int at, unsigned long int n); // s.cut(3,2);
- // remove the substring of length "n" starting at letter # "at".
- // (The first character of the string is character # 1.)
- // If either parameter is out of range, only the valid part is cut.
- // If n==0, no change is done to the NString.
- // The function returns a reference to the modified NString; the
- // cut part is lost.
-
- /*-------- Iterator --------*/
-
- enum direction_t {FORWARD, BACKWARD};
-
- NString& through(int (*action)(const char, const unsigned long int, NString&), direction_t dir = FORWARD);
- // traverse the NString in the specified directon, calling at each step the given function.
- // The "action" function receives as parameters the current character, its position in
- // the NString (starting from 1) and a reference to the NString being traversed.
- // If the NString is empty, the iterator does nothing.
- // If the NString is altered during iteration, these modifications will NOT affect the iteration
- // process, as the string being traversed is actually a copy of the original string.
- // The "action" may interrupt the iteration process by returning a non-zero value.
- // Zero must be returned for the iteration to proceed until the end of the string is reached.
- // The iterator returns a reference to the NString being traversed.
-
- // Example: "s.through(&print, NString::BACKWARD)" where print() has been previously defined;
-
- /*-------- Transforming NStrings --------*/
-
- NString upcase (void) const; // t = s.upcase();
- // get a new NString consisting of the original one converted to upper case.
-
- NString lowcase (void) const; // t = s.lowcase();
- // get a new NString consisting of the original one converted to lower case.
-
- NString& toupcase (void); // s.toupcase();
- // convert this NString to uppercase.
-
- NString& tolowcase (void); // s.tolowcase();
- // convert this NString to lowercase.
-
- NString& clear (void); // s.clear();
- // clear this NString.
-
- /*-------- Getting context position in an NString --------*/
-
- unsigned long int leftpos (const char *s) const; // k = s.leftpos("loop");
-
- unsigned long int leftpos (const char c) const; // k = s.leftpos('L');
-
- inline unsigned long int leftpos (const NString& s) const; // k = s.leftpos(t);
-
- unsigned long int leftpos (const Alphabet& a) const; // k = s.leftpos(alpha);
- // return the position of the leftmost occurrence of
- // the context in the NString.
- // The first character of the NString has position 1.
- // If an occurrence cannot be found, zero is returned.
- // If the context is an empty string, leftpos() returns 1,
- // as an empty string can be found everywhere.
-
-
- unsigned long int rightpos (const char *s) const; // k = s.rightpos("end");
-
- unsigned long int rightpos (const char c) const; // k = s.rightpos('R');
-
- inline unsigned long int rightpos (const NString& s) const; // k = s.rightpos(t);
-
- unsigned long int rightpos (const Alphabet& a) const; // k = s.rightpos(alpha);
- // return the position of the rightmost occurrence of
- // the context in the NString.
- // The first character of the NString has position 1.
- // If an occurrence cannot be found, zero is returned.
- // If the context is an empty string, rightpos() returns "s.length()+1",
- // as an empty string can be found everywhere.
- // In the case of an alphabet-context, the result is the position
- // of the first letter that is encountered when scanning the NString
- // backwards AND that is contained in the alphabet. For example,
- // if "alpha" contains the letters 'a', 'm' and 'r', and the NString "s"
- // contains the string "Superman", the call "s.rightpos(alpha)"
- // returns the value 7, i.e. the position of the letter 'a'.
-
- /*-------- Copying context-dependant parts of an NString --------*/
-
- NString leftof (const char *context) const; // t = s.leftof("begin");
-
- NString leftof (const char context) const; // t = s.leftof('b');
-
- NString leftof (const NString& context) const; // t = s.leftof(t);
-
- NString leftof (const Alphabet& context) const; // t = s.leftof(alpha);
- // return the initial part of the NString not containing
- // the leftmost context occurrence.
- // The result of this function will be:
- // • context occurrence not found: the entire NString
- // • context occurrence at position 1: an empty NString
- // • context occurrence not starting at position 1: "to(leftpos(context)-1)"
-
-
- NString atleft (const char *context) const; // t = s.atleft("begin");
-
- NString atleft (const char context) const; // t = s.atleft('b');
-
- NString atleft (const NString& context) const; // t = s.atleft(t);
-
- NString atleft (const Alphabet& context) const; // t = s.atleft(alpha);
- // return the final part of the NString starting at the position of
- // the leftmost context occurrence.
- // The result of this function will be:
- // • context occurrence not found: an empty NString
- // • context occurrence found and context is not empty string: "from(leftpos(context))"
- // • context is empty string: the entire NString
- // The following test will always yield true: (s == s.leftof(context) + s.atleft(context))
-
-
- NString toleft (const char *context) const; // t = s.toleft("while");
-
- NString toleft (const char context) const; // t = s.toleft('w');
-
- NString toleft (const NString& context) const; // t = s.toleft(t);
-
- NString toleft (const Alphabet& context) const; // t = s.toleft(alpha);
- // return the initial part of the NString just containing the
- // leftmost occurrence of the context.
- // The result of this function will be:
- // • context occurrence not found: the entire NString
- // • context occurrence found and context is not empty string: "to(leftpos(context) + context_length - 1)"
- // • context is empty string: an empty NString
-
-
- NString leftcut (const char *context) const; // t = s.leftcut("while");
-
- NString leftcut (const char context) const; // t = s.leftcut('w');
-
- NString leftcut (const NString& context) const; // t = s.leftcut(t);
-
- NString leftcut (const Alphabet& context) const; // t = s.leftcut(alpha);
- // return the final part of the NString starting after
- // and not containing the leftmost occurrence of the context.
- // The result of this function will be:
- // • context occurrence not found: an empty NString
- // • context is empty string: the entire NString
- // • context occurrence found and context is not empty string: "from(leftpos(context) + context_length)"
- // The following test will always yield true: (s == s.toleft(context) + s.leftcut(context))
-
-
- NString rightof (const char *context) const; // t = s.rightof("begin");
-
- NString rightof (const char context) const; // t = s.rightof('b');
-
- NString rightof (const NString& context) const; // t = s.rightof(t);
-
- NString rightof (const Alphabet& context) const; // t = s.rightof(alpha);
- // return the final part of the NString not containing
- // the rightmost context occurrence.
- // The result of this function will be:
- // • context occurrence not found: the entire NString
- // • context occurrence at the end of the string: an empty NString
- // • context occurrence not ending the string: "from(rightpos(context) + context_length)"
-
-
- NString atright (const char *context) const; // t = s.atright("begin");
-
- NString atright (const char context) const; // t = s.atright('b');
-
- NString atright (const NString& context) const; // t = s.atright(t);
-
- NString atright (const Alphabet& context) const; // t = s.atright(alpha);
- // return the final part of the NString starting at the position of
- // the rightmost context occurrence.
- // The result of this function will be:
- // • context occurrence not found: the entire NString
- // • context occurrence found and context is not empty string: "from(rightpos(context))"
- // • context is empty string: an empty NString
-
-
- NString toright (const char *context) const; // t = s.toright("while");
-
- NString toright (const char context) const; // t = s.toright('w');
-
- NString toright (const NString& context) const; // t = s.toright(t);
-
- NString toright (const Alphabet& context) const; // t = s.toright(alpha);
- // return the initial part of the NString just containing the
- // rightmost occurrence of the context.
- // The result of this function will be:
- // • context occurrence not found: an empty NString
- // • context occurrence found and context is not empty string: "to(rightpos(context) + context_length - 1)"
- // • context is empty string: the entire NString
- // The following test will always yield true: (s == s.toright(context) + s.rightof(context))
-
-
- NString rightcut (const char *context) const; // t = s.rightcut("while");
-
- NString rightcut (const char context) const; // t = s.rightcut('w');
-
- NString rightcut (const NString& context) const; // t = s.rightcut(t);
-
- NString rightcut (const Alphabet& context) const; // t = s.rightcut(alpha);
- // return the initial part of the NString ending at
- // and not containing the rightmost occurrence of the context.
- // The result of this function will be:
- // • context occurrence not found: an empty NString
- // • context occurrence found at the beginning of the string: an empty NString
- // • context is empty string: the entire NString
- // • context occurrence found and context is not empty string: "to(rightpos(context) - 1)"
- // The following test will always yield true: (s == s.rightcut(context) + s.atright(context))
-
-
- inline char leftocc (const Alphabet& a) const; // c = s.leftocc(Alphabet("abc"));
- // of the letters contained in the alphabet, return the one that
- // has the leftmost position in the NString. If there is no such letter
- // in the alphabet, the NUL-character ('\0') is returned, as this
- // character cannot be part of any NString.
-
- inline char rightocc (const Alphabet& a) const; // c = s.rightocc(Alphabet("abc"));
- // of the letters contained in the alphabet, return the one that
- // has the rightmost position in the NString. If there is no such letter
- // in the alphabet, the NUL-character ('\0') is returned, as this
- // character cannot be part of any NString.
-
-
- friend NString span (const char context, const NString& s); // t = span('-', s);
-
- friend NString span (const Alphabet& context, const NString& s); // t = span(alpha, s);
- // return the initial substring of the NString "s" that
- // consists of nothing but "context"-characters.
- // e.g: span("-", NString("--Test==")) would return "--".
-
- friend NString span (const NString& s, const char context); // t = span(s, '*');
-
- friend NString span (const NString& s, const Alphabet& context); // t = span(s, alpha);
- // return the final substring of the NString "s" that
- // consists of nothing but "context"-characters.
-
-
- friend NString operator- (const char c, const NString& s); // t = '*' - s;
-
- friend NString operator- (const Alphabet& ctx, const NString& s); // t = alpha - s;
- // return the final part of the NString "s" that remains
- // when all of the initial occurrences of the context
- // have been stripped.
-
- NString operator- (const char c) const; // t = s - ')';
-
- NString operator- (const Alphabet& ctx) const; // t = s - alpha;
- // return the initial part of the NString that remains
- // when all of the final occurrences of the context
- // have been stripped.
-
- NString& operator-= (const char c); // s -= '0';
-
- NString& operator-= (const Alphabet& ctx); // s -= alpha;
- // remove all of the initial occurrences of the context
- // from the NString.
-
- /*-------- Context-related tests --------*/
-
- inline int startswith (const char *context) const; // if (s.startswith("repeat")) ...
-
- inline int startswith (const char context) const; // if (s.startswith('Q')) ...
-
- inline int startswith (const NString& context) const; // if (s.startswith(t)) ...
-
- inline int startswith (const Alphabet& context) const; // if (s.startswith(alpha)) ...
- // return non-zero if the NString starts with the given context,
- // zero otherwise.
-
-
- int endswith (const char *context) const; // if (s.endswith("repeat")) ...
-
- inline int endswith (const char context) const; // if (s.endswith('Q')) ...
-
- inline int endswith (const NString& context) const; // if (s.endswith(t)) ...
-
- inline int endswith (const Alphabet& context) const; // if (s.endswith(alpha)) ...
- // return non-zero if the NString ends with the given context,
- // zero otherwise.
-
-
- inline int contains (const char *context) const; // if (s.contains("take")) ...
-
- inline int contains (const char context) const; // if (s.contains('<')) ...
-
- inline int contains (const NString& context) const; // if (s.contains(t)) ...
-
- inline int contains (const Alphabet& context) const; // if (s.contains(alpha)) ...
- // return non-zero if the NString (entirely) contains the given context,
- // zero otherwise. In the case of an alphabet, this means that
- // EVERY letter of the alphabet must be contained in the NString.
- // If "context" is an empty alphabet, non-zero is returned.
-
-
- inline int disjointed (const Alphabet& alpha) const; // if (s.disjointed(alpha)) ...
- // return non-zero iff none of the alphabet's letters
- // occurs in the NString, zero otherwise.
- // If "alpha" is empty, non-zero is returned.
-
-
- /*-------- Input / Output --------*/
-
- friend ostream& operator<< (ostream& theStream, const NString& theString); // cout << s;
- // output the NString onto the stream "theStream".
- // Field width and fill character are supported in the same way
- // as for C-strings.
-
- friend istream& operator>> (istream& theStream, NString& theString); // cin >> s;
- // skip whitespace, then input a character string from "theStream"
- // and store it in "theString". Whitespace following the string
- // is treated as terminator and left on the stream for subsequent reads.
- // The NUL character is considered whitespace in this context.
- // Field width and the "ios::skipws" flag are currently ignored.
- // If the operator is used on a stream that is not in good condition,
- // the operation is a null operation and "theString" is left unmodified.
- // Note that a call like "cin >> s" is perfectly safe if "s" is an NString,
- // as NStrings dynamically allocate the needed memory.
-
- friend istream& get (istream& theStream, NString& theString,
- const unsigned long int maxLength, const char terminator = '\n');
- // input characters from the stream "theStream" into the NString "theString",
- // but don't make the string any longer than "maxLength".
- // If "maxLength" == 0, this constraint is ignored.
- // If a "terminator" character is encountered, it is left on the stream for
- // subsequent reads and the current input process terminates.
- // "terminator" may be set to '\0', if no special terminator character is
- // desired.
- // Whitespace is treated as any other character.
- // NUL characters preceding useful string data are skipped.
- // A NUL character following string data always acts like a terminator.
- // If the function is used on a stream that is not in good condition,
- // the operation is a null operation and "theString" is left unmodified.
-
- friend inline istream& get (istream& theStream, NString& theString, const char terminator = '\n');
- // equivalent to the preceding "get()" function, but without string length limitation.
-
-
- inline NString& operator<< (const char *s);
- inline NString& operator<< (const NString& s);
- inline NString& operator<< (const char c);
- NString& operator<< (const unsigned long int n);
- NString& operator<< (const signed long int n);
- NString& operator<< (const unsigned short int n);
- NString& operator<< (const signed short int n);
- NString& operator<< (const double n);
- NString& operator<< (const float n);
- NString& operator<< (const void *p);
- inline NString& operator<< (NString& (*manip)(NString&));
-
- // append the given data to the NString "out". This way an NString can be used
- // in a way similar to an output string stream. For example, if s is an empty
- // NString and t is an NString containing "apple", the following line:
- // s << "I don't know the word " << t << '.';
- // would write the string "I don't know the word apple." into s.
- //
- // In this version, the following conventions have been used:
- // • floats are output with 6 decimal digits, doubles with 12;
- // • integers are converted as decimal values.
-
- friend inline NString& endl (NString& s);
- friend inline NString& clear (NString& s);
- // Currently, the only manipulators that are defined are "endl" and "clear",
- // used to append '\n' to, resp. to clear the NString. Using other predefined manipulators,
- // such as "hex" or "setprecision" does not yet produce the desired effect.
- // Other manipulators may be defined by the class user, though.
-
-
- /*-------- Memory Management --------*/
-
- static int SetBufferSizeStep (unsigned long int NewSizeStep);
- // permit the class-user to change the Buffer Size Step value. Buffer size for any NString
- // will be kept at a multiple bytes of this value. NewSizeStep must be a strictly positive
- // integer. The function returns 0 on failure, 1 on success.
- // The default Buffer Size Step is 100 bytes.
-
- static unsigned long int GetBufferSizeStep (void);
- // return the current Buffer Size Step value.
-
- static int SetDeallocationTrigger (float NewValue);
- // set a new value for DeallocationTrigger. This value ranging from 0.0 to 0.99
- // assures that an additional BufferSizeStep bytes that have been allocated are not
- // freed when the new buffer size would drop just below the next BufferSizeStep limit.
- // Example: Suppose you have a string of 102 bytes and the default values for BufferSizeStep (100 bytes)
- // and DeallocationTrigger (0.2, the equivalent of 20%). The string's internal buffer has thus
- // been sized at 200 bytes. By now cutting out of this string a substring of, let's say, 20 bytes,
- // the string length drops to 82 bytes. Still, the internal buffer size remains unchanged (200 bytes)
- // until the string is shortened by a further 3 bytes, because the limit is situated at 80 bytes,
- // which represent 80% of the current BufferSizeStep. You can set this limit by specifying a
- // DeallocationTrigger value equal to the remaining 20% necessary to complete the unit.
- // This technique avoids frequent buffer reallocations for strings that often change their size
- // as long as it stays close to a multiple of BufferSizeStep. "SetDeallocationTrigger()" returns
- // 0 if the new value could not be accepted, 1 on success.
-
- static float GetDeallocationTrigger (void);
- // return the current DeallocationTrigger value.
-
-
- /*-------- Error Handling --------*/
-
- #ifdef USE_EXCEPTIONS
-
- class Exception
- {
- public:
-
- enum { MAX_MSG_LENGTH = 255 };
-
- const unsigned long int ErrorLine;
- char ErrorFile[MAX_MSG_LENGTH + 1];
- char ErrorFunction[MAX_MSG_LENGTH + 1];
- char ErrorMessage[MAX_MSG_LENGTH + 1];
-
- Exception (const unsigned long int line, const char *file, const char *function, const char *message);
-
- ~Exception (void) {}
-
- virtual void PrintError (ostream& theStream = cerr);
- };
-
- class OutOfMemory : public Exception
- {
- public:
- OutOfMemory (const unsigned long int line, const char *file, const char *function)
- : Exception (line, file, function, "Out of memory") {}
- };
-
- class UsageError : public Exception
- {
- public:
- UsageError (const unsigned long int line, const char *file, const char *function, const char *message)
- : Exception (line, file, function, message) {}
- };
-
- // Note: Generally, if an exception is thrown, the NString remains in a coherent state.
- // Still, in certain cases, the NString may already have been modified before the error condition
- // was detected.
-
- #else
-
- static void (*panic)(const unsigned long int line, const char *file,
- const char *function, const char *message);
- // vector pointing to a (fatal) error-handling routine for systems without exception support.
- // The vector may be altered by the user to point to a user-defined error-handling routine.
- // CAUTION: The routine pointed to by this vector MUST NOT return to the caller !!
-
- static void NString_Error (const unsigned long int line, const char *file,
- const char *function, const char *message);
- // primitive error-handling routine for compiling on those systems that do not yet have
- // exception handling support. Prints a message to standard out, then exits with return code 1.
-
- #endif
-
-
- private:
-
- struct strbody
- {
- unsigned long int len; // the string's length, without the terminating NUL
- unsigned long int bufsize; // the size of the buffer pre-allocated for the string data
- char *str; // the string as a null-terminated C-String
- unsigned int refs; // the number of instances that currently use this strbody
-
- inline strbody(); // constructor to initialize a strbody struct
- };
-
- strbody *sb; // the instance's pointer to the actual (shared) data
-
-
- int DuplicateSB (void);
- // duplicate the current string body (including its string buffer), then connect self to the copy.
- // Will NOT deallocate the old body, even if now unused,
- // thus should not be called when (sb->refs == 1).
- // If duplication fails, the current string body remains untouched and zero is returned.
- // A non-zero value is returned on success.
-
- int GetNewSB (unsigned long int new_length);
- // disconnect self from old string body, then replace it by a new one of length "new_length".
- // Actual buffer "sb->str" will have length "new_length"+1 (plus the bytes necessary to make
- // the size a multiple of BufferSizeStep).
- // A zero-byte is placed automatically at the ending position of the future string in the buffer,
- // even though the buffer is not yet completely initialized. Also, the new length is inscribed
- // into the new string body.
- // If allocation fails, the current string body remains untouched and zero is returned.
- // A non-zero value is returned on success.
-
- NString (const unsigned long int l);
- // constructor: create an uninitialized NString with a bufferlength of (at least) "l+1".
- // A zero-byte is placed automatically at the ending position of the future string in the buffer,
- // even though the buffer is not yet completely initialized.
-
-
- static unsigned long int BufferSizeStep;
- // the buffer size for any NString will be kept at a multiple bytes of this value. May be modified
- // with the public method "SetBufferSizeStep()".
-
- static float DeallocationTrigger;
- // see the explanation for the public routine "SetDeallocationTrigger()" ...
-
- static unsigned long int DeallocationMargin;
- // when a buffer size decrease of exactly BufferSizeStep bytes is asked, it is only done
- // if there is at least a distance of DeallocationMargin bytes between the non-aligned new size
- // and the next multiple of BufferSizeStep. This value is set internally based on the formula:
- // DeallocationMargin = DeallocationTrigger * BufferSizeStep
-
-
- char *AllocStrBuf (unsigned long int size);
- // try to allocate the nearest multiple to "size+1" of "BufferSizeStep" bytes for the
- // string buffer inside the current stringbody, then inscribe string length (== "size")
- // and actual buffer size (multiple of "BufferSizeStep") into the stringbody.
- // This is a low level routine that ignores the number of references to the stringbody.
- // Return the pointer to the allocated memory block, NULL on failure.
- // If the allocation fails, the string body is left unchanged.
-
- char *ReallocStrBuf (unsigned long int size);
- // try to modify the size of the current stringbody's buffer to the nearest multiple to "size+1"
- // of "BufferSizeStep" bytes. Inscribe the new buffer size into the stringbody.
- // The new length of the string is NOT inscribed in the string body; this must be done by the caller !
- // This is a low level routine that ignores the number of references to the stringbody.
- // Return the pointer to the new memory block, NULL on failure.
- // If the reallocation fails, the string body is left unchanged.
-
- #ifndef USE_EXCEPTIONS
-
- static void Out_of_Memory (unsigned int line, const char *file, const char *function);
- // prepare "out of memory" message to pass to the "panic" routine.
- // Useful on systems without exception support.
-
- #endif
-
- /*-------- Friends in the alphabet class --------*/
-
- friend Alphabet::Alphabet (const NString& source);
- friend Alphabet& Alphabet::operator= (const NString& source);
- friend Alphabet& Alphabet::operator+= (const NString& source);
- friend inline Alphabet Alphabet::operator+ (const NString& source) const;
- friend Alphabet& Alphabet::operator-= (const NString& source);
- friend int Alphabet::contains (const NString& elements) const;
- friend inline Alphabet& Alphabet::operator*= (const NString& string);
- friend inline Alphabet Alphabet::operator* (const NString& string) const;
- friend inline int Alphabet::operator== (const NString& other) const;
- friend inline int Alphabet::operator!= (const NString& other) const;
- friend inline int Alphabet::operator<= (const NString& other) const;
- friend inline int Alphabet::operator< (const NString& other) const;
-
-
- // SOME WORDS ON COMPILING:
- //
- // When compiling the NString and Alphabet classes, you may define
- // the macro NSTRING_DEBUG to be a non-zero value. According to the bits
- // that are set in NSTRING_DEBUG, various information is written to stdout:
- // set bit 0 to show calls to Alphabet constructors;
- // set bit 1 to show calls to NString constructors and destructors;
- // set bit 2 to show memory allocation concerning the NString internal buffer.
- //
- // Furthermore, you may compile the classes with the macro USE_EXCEPTIONS defined
- // to create exception-supporting code.
- //
- // WARNING: Be sure to use the same compiler settings when compiling a project
- // that uses a precompiled version of the NString/Alphabet classes, as were used
- // when compiling the library. It would be a good idea to use standard ANSI settings
- // in both cases. For example, tell the compiler to always treat "enums" as "ints",
- // otherwise some functions that take "enum" parameters, such as "NString::through()"
- // or "Alphabet::through()" will probably cause your program to crash !
-
-
- // NEEDED STUFF FOR CLASS USAGE:
- //
- // Once the NString and Alphabet classes are compiled into a library or an object file,
- // you will need to link it into your application to use it. Moreover, the following
- // include files must remain accessible, and should be stored together in one directory:
- //
- // - NString.h
- // - Alphabet.h
- // - NString_Inlines.h
- // - Alphabet_Inlines.h
- //
- // Usually it will suffice that you #include "NString.h", the other files are included
- // automatically. If usage of the Alphabet class is desired without the need for NString,
- // it should be sufficient to #include "Alphabet.h".
- //
- // It is also necessary to link your projects with a library containing the iostreams
- // routines, otherwise you might get link errors, as NString uses these routines.
-
- };
-
- #include "NString_Inlines.h"
-
- #endif
-